package com.yenlien.traceyun.plant.service;

import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.interceptor.UserAuthUtil;
import com.yenlien.traceyun.business.service.rest.usercenter.UserRestService;
import com.yenlien.traceyun.common.bean.UserInfo;
import com.yenlien.traceyun.common.crypt.CryptUtil;
import com.yenlien.traceyun.plant.dao.ColdStorageCompDao;
import com.yenlien.traceyun.plant.dao.ColdUserDao;
import com.yenlien.traceyun.plant.entity.ColdStorageComp;
import com.yenlien.traceyun.plant.entity.ColdUser;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Date 2022/8/30
 * @Author jiaLong
 * @Descript
 */
@Service
public class ColdStorageCompService {
    @Autowired
    private ColdStorageCompDao coldStorageCompDao;
    @Autowired
    private UserRestService userRestService;
    @Autowired
    private ColdUserDao coldUserDao;

    @Transactional
    public ColdStorageComp save(ColdStorageComp coldStorageComp) {
        if(StringUtils.isEmpty(coldStorageComp.getId())){
            if(!StringUtils.isEmpty(coldStorageComp.getPassword()) && !StringUtils.isEmpty(coldStorageComp.getMakeSurePassword())){
                if(!coldStorageComp.getPassword().equals(coldStorageComp.getMakeSurePassword())){
                    throw new BusinessException("两次输入密码不一致");
                }
            }else
                coldStorageComp.setPassword("123123");
            coldStorageComp.setState("1");
            if(StringUtils.isEmpty(coldStorageComp.getIsManage()))
                coldStorageComp.setIsManage("2");
            ColdStorageComp save = coldStorageCompDao.save(coldStorageComp);

//            Map<String, Object> user = new HashMap<>();
//            user.put("companyId", save.getId());
//            user.put("phone", save.getPhone());
//            user.put("username", save.getPrincipal());
//            user.put("password", coldStorageComp.getPassword());
//            user.put("name", save.getAbbreviation());
//            user.put("isManage", save.getIsManage());
//            userRestService.save(user, null);
            // 西昌用户
            if(!CollectionUtils.isEmpty(coldUserDao.findByPhone(save.getPhone()))){
                throw new BusinessException("账号已存在");
            }
            ColdUser coldUser = new ColdUser(save.getAbbreviation(), save.getPhone(), CryptUtil.md5(save.getPassword()), save.getName(), save.getId(), save.getIsManage(), "2");
            coldUserDao.save(coldUser);
            return save;
        }else {
            return coldStorageCompDao.save(coldStorageComp);
        }
    }


    public ColdStorageComp findById(String id){
        return coldStorageCompDao.findById(id).orElseThrow(() -> new BusinessException("该主体不存在"));
    }


    public Page<ColdStorageComp> findByList(ColdStorageComp coldStorageComp) {
        UserInfo userInfo = UserAuthUtil.getLoginUser();
//        if(StringUtils.isEmpty(coldStorageComp.getIsManage())){
//            coldStorageComp.setIsManage(userInfo.getIsManage());
//        }
        Pageable pageable = PageRequest.of(coldStorageComp.getPage(), coldStorageComp.getPageSize(), Sort.Direction.DESC, "createTime");
        return coldStorageCompDao.findAll((Root<ColdStorageComp> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genSelectParam(root, cb, coldStorageComp);
        }, pageable);
    }

    public List<ColdStorageComp> export(ColdStorageComp coldStorageComp) {
        return coldStorageCompDao.findAll((Root<ColdStorageComp> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            return genSelectParam(root, cb, coldStorageComp);
        });
    }


    public List<JSONObject> findComp(String lng, String lat){
        List<JSONObject> compList = coldStorageCompDao.findComp();
        if (StringUtils.isEmpty(lng))
            return compList;
        return compList.stream().map(x -> {
            String coordinate = x.getString("coordinate");
            if(StringUtils.isEmpty(coordinate)){
                return x;
            }
            String[] coordinate2 = coordinate.split(",");
            double distance = getDistance(Double.valueOf(lat), Double.valueOf(lng), Double.valueOf(coordinate2[1]), Double.valueOf(coordinate2[0]));
            x.put("distance", distance);
            return x;
        }).sorted(Comparator.comparing(x -> x.getDouble("distance"))).collect(Collectors.toList());
    }


    /**
     * 根据两个位置的经纬度，来计算两地的距离（单位为KM）
     * @param lat1 纬度
     * @param lng1 经度
     * @param lng2
     * @param lat2
     * @return
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double patm = 2;
        double radLat1 = (lat1 * Math.PI / 180.0);
        double radLat2 = (lat2 * Math.PI / 180.0);
        double difference = radLat1 - radLat2;
        double mdifference = (lng1 * Math.PI / 180.0) - (lng2 * Math.PI / 180.0);
        double distance = patm * Math.asin(Math.sqrt(Math.pow(Math.sin(difference / patm), patm)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(mdifference / patm), patm)));
        distance = distance * 6378.137; //6378.137是赤道的半径  单位为 KM
        return distance;
    }


    public List<ColdStorageComp> findAll(){
        return coldStorageCompDao.findAll();
    }

    public List<ColdStorageComp> findByStateAndId(String state){
        UserInfo userInfo = UserAuthUtil.getLoginUser();
        if(!"1".equals(userInfo.getIsManage())){
            return coldStorageCompDao.findByIdAndState(userInfo.getCompanyId(), state);
        }
        return coldStorageCompDao.findByState(state);
    }



    public Predicate genSelectParam(Root<ColdStorageComp> root, CriteriaBuilder cb, ColdStorageComp coldStorageComp){
        UserInfo userInfo = UserAuthUtil.getLoginUser();
        List<Predicate> list = new ArrayList<>();
        if (!StringUtils.isEmpty(coldStorageComp.getName()))
            list.add(cb.like(root.get("name"), "%" + coldStorageComp.getName() + "%"));

        if (!StringUtils.isEmpty(coldStorageComp.getCompType()))
            list.add(cb.equal(root.get("compType"), coldStorageComp.getCompType()));
        else
            list.add(cb.isNull(root.get("compType")));

        if (!StringUtils.isEmpty(coldStorageComp.getAddress()))
            list.add(cb.like(root.get("address"), "%" + coldStorageComp.getAddress() + "%"));

        if("2".equals(userInfo.getIsManage()))
            list.add(cb.equal(root.get("id"), userInfo.getCompanyId()));

        if(!"1".equals(userInfo.getIsManage())){
//            list.add(cb.equal(root.get("id"), userInfo.getCompanyId()));
            list.add(cb.equal(root.get("isManage"), coldStorageComp.getIsManage()));
        }
//        if("2".equals(userInfo.getIsManage())){
//            list.add(cb.like(root.get("id"), userInfo.getCompanyId()));
//        }
//        if("3".equals(userInfo.getIsManage()) || "4".equals(userInfo.getIsManage())){
//            list.add(cb.like(root.get("compType"), coldStorageComp.getCompType()));
//        }
        return cb.and(list.toArray(new Predicate[list.size()]));
    }




}
